package bairui.international.data;

import java.io.File;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.sh_lianjing.file.excel.bean.RowInfo;
import com.sh_lianjing.file.excel.bean.SheetInfo;
import com.sh_lianjing.file.excel.read.ExcelReaderBeanSupport;
import com.sh_lianjing.file.excel.read.annotation.ReadExcel;
import com.sh_lianjing.file.excel.read.annotation.ReadExcelCell;
import com.sh_lianjing.file.excel.read.parsevisitor.ExcelParseVisitorSupport;

import bairui.international.model.domain.jpa.TB_City;
import bairui.international.model.domain.jpa.TB_Province;
import bairui.international.model.domain.jpa.TB_Town;
import bairui.international.service.Service_City;
import bairui.international.service.Service_Province;
import bairui.international.service.Service_Town;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.Setter;

public class Data_ImportPlace {
	
	private static String ReplaceChar = " ";
	
	private static File file = new File("../../文档/2019年10月中华人民共和国县以上行政区划代码.xlsx");
	
	@AllArgsConstructor
	@NoArgsConstructor
	@ReadExcel
	public static class InputBean {
		@JsonIgnore private @Setter @ReadExcelCell(headPattern = ".*行政区划代码.*") String code;
		@JsonIgnore private @Setter @ReadExcelCell(headPattern = ".*单位名称.*") String name;
		
		public String getCode() {
			if(null == code){
				return null;
			}
			return code.replaceAll(ReplaceChar, "").trim();
		}
		public String getName() {
			if(null == name){
				return null;
			}
			return name.replaceAll(ReplaceChar, "").trim();
		}
	}
	
	/**
	 * 省
	 */
	@NoArgsConstructor
	public static class Province extends InputBean {
		public Province(String code, String name) {
			super(code, name);
		}
		@Override public boolean equals(Object obj) {
			return getCode().substring(0, 2)
					.equals(((Province)obj).getCode().substring(0, 2));
		}
		@Override public int hashCode() {
			return getCode().substring(0, 2).hashCode();
		}
		@Override public String toString() {
			return "省：{code="+ this.getCode() +", name="+ this.getName() +"}";
		}
	}
	
	/**
	 * 市
	 */
	@NoArgsConstructor
	public static class City extends InputBean {
		public City(String code, String name) {
			super(code, name);
		}
		@Override public boolean equals(Object obj) {
			return getCode().substring(2, 4)
					.equals(((City)obj).getCode().substring(2, 4));
		}
		@Override public int hashCode() {
			return getCode().substring(2, 4).hashCode();
		}
		@Override public String toString() {
			return "市：{code="+ this.getCode() +", name="+ this.getName() +"}";
		}
	}
	
	/**
	 * 县
	 */
	@NoArgsConstructor
	public static class Town extends InputBean {
		public Town(String code, String name) {
			super(code, name);
		}
		@JsonProperty @Override public String toString() {
			return "县：{code="+ this.getCode() +", name="+ this.getName() +"}";
		}
	}
	
	public static void main(String[] args) throws Exception {
		importData(null, null, null);
	}
	
	public static void importData(Service_Province service_Province, Service_City service_City, Service_Town service_Town) throws Exception {
		/*
		 * 导入数据
		 */
		List<InputBean> beans = new ArrayList<>();
		try(ExcelReaderBeanSupport read = new ExcelReaderBeanSupport(file)){
			read.read(InputBean.class, new ExcelParseVisitorSupport<InputBean>() {
				@Override public void run(SheetInfo<Sheet> sheetInfo, RowInfo<Row> rowInfo, Map<String, List<String>> head, InputBean e) {
					beans.add(e);
				}
			});
		}
		/*
		 * 建立数据结构
		 */
		Map<Province, Map<City, List<Town>>> map = beans
			.stream()
			.collect(Collectors.groupingBy(
				item->{
					return new Province(item.getCode(), item.getName());
				}, 
				LinkedHashMap::new, 
				Collectors.groupingBy(
					item2->{
						return new City(item2.getCode(), item2.getName());
					},
					LinkedHashMap::new, 
					Collectors.mapping(item3->new Town(item3.getCode(), item3.getName()), Collectors.toList())
				)
			));
		
		/*
		 * 清理数据
		 */
		map.forEach((_province, _cityMap)->{
			String provinceCode = _province.getCode();
			// 移除与省重复的市
			_cityMap.keySet().removeIf(it->{
				return it.getCode().equals(provinceCode);
			});
			// 移除与市重复的县
			_cityMap.entrySet().forEach(e->{
				String cityCode = e.getKey().getCode();
				List<Town> towns = e.getValue();
				towns.removeIf(town->{
					return town.getCode().equals(cityCode);
				});
			});
		});
		// 移除没有市的项
		map.values().removeIf(it->it.isEmpty());
		
		/*
		 * 打印数据
		 */
//		map.forEach((k,v)->{
//			System.out.println(k + "===" + v);
//			v.forEach((k2,v2)->{
//				System.out.println("	"+ k2 + "====" + v2);
//			});
//		});
		
		/*
		 * 保存到数据库
		 */
		map.forEach((_province, _cityMap)->{
			// 省
			TB_Province province = new TB_Province(new TB_Province.MustProperties() {
				@Override public String getName() {
					return _province.getName();
				}
				@Override public String getCode() {
					return _province.getCode();
				}
			});
			// 市
			_cityMap.forEach((_city, _towns)->{
				TB_City city = new TB_City(new TB_City.MustProperties() {
					@Override public TB_Province getProvince() {
						return province;
					}
					@Override public String getName() {
						return _city.getName();
					}
					@Override public String getCode() {
						return _city.getCode();
					}
				});
				if(service_City.exists(it->it.code.eq(city.getCode()))){
					service_City.update(city.getCode(), city.getName());
				}else{
					TB_Province p = service_Province.findOne(it->it.code.eq(province.getCode()));
					if(null != p){
						city.setProvince(p);
						service_City.save(city);
					}else{
						province.addCities(city);
					}
				}
				// 县
				_towns.forEach(_town->{
					TB_Town town = new TB_Town(new TB_Town.MustProperties() {
						@Override public String getName() {
							return _town.getName();
						}
						@Override public String getCode() {
							return _town.getCode();
						}
						@Override public TB_City getCity() {
							return city;
						}
					});
					if(service_Town.exists(it->it.code.eq(town.getCode()))){
						service_Town.update(town.getCode(), town.getName());
					}else{
						TB_City c = service_City.findOne(it->it.code.eq(city.getCode()));
						if(null != c){
							town.setCity(c);
							service_Town.save(town);
						}else{
							city.addTowns(town);
						}
					}
				});
			});
			// 保存
			if(service_Province.exists(it->it.code.eq(province.getCode()))){
				service_Province.update(province.getCode(), province.getName());
			}else{
				service_Province.save(province);
			}
		});
		
	}
	
}
